// 知识点1：new和delete运算符的实现细节：

// new的操作过程：第一步、new表达式调用operator new(或者 operator
// new[])的标准库函数，该函数分配一块足够大的、原始的、未命名的内存空间以便存储特定类型的对象（或数组）。第二步、编译器运行相应的构造函数以构造这些对象，并为其传入初始值。第三步、对象分配了空间并构造完成，返回一个指向该对象的指针

// delete的操作过程：第一步：对指针所指对象的数组指针所指数组执行相应的析构函数。第二步：编译器调用operator
// delete（或者operator delete[]）的标准库函数释放内存空间

// 知识点2：在自定义这两个标准库函数的时候，一定要弄对，因为这对计算机来说至关重要！

// 知识点3：重载new和delete，其实就是重载标准库的相关的两个operator函数

// 知识点4：实现的过程：若分配（释放）的对象是类类型，则编译器首先在类及其基类的作用域中查找，若该类中含有operator
// new成员或者operator
// delete成员，则相应表达式将调用这些成员，否则，编译器将在全局作用域查找匹配函数，若找到用户自定义版本，则执行，找不到，会使用标准库版本

// 知识点5：我们为一个对象分配空间时使用operator
// new，为一个数组分配空间时使用operator new[]

// 知识点6：C++从C语言中继承了malloc和free函数，头文件为cstdlib，malloc接受一个表示待分配字节数的size_t，返回指向该内存空间的指针或者返回0表示分配失败。free()函数接受一个void
// *，它是malloc返回指针的副本，free将相关内存返回给系统，free(0)无意义。所以operator
// new可以用malloc来实现
#include <cstdlib>
#include <iostream>

void *operator new(std::size_t n) {
  std::cout << "new(size_t)" << std::endl;
  if (void *mem = malloc(n))
    return mem;
  else
    throw std::bad_alloc();
}
void operator delete(void *mem) noexcept {
  std::cout << "delete(void*)<<endl";
  free(mem);
}
int main() {
  using namespace std;
  int *a = new int(486);
  cout << a << " " << *a << endl;
  delete a;
  system("pause");
  return 0;
}